/*****************************************************************************
 *   Copyright 2005 Tim A Wang
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 ****************************************************************************/
package com.jb.web.renderer;

import com.jb.web.application.HtmlConstants;
import com.jb.web.bean.Menu;
import com.jb.web.bean.MenuItem;
import com.jb.web.context.WebContext;

import com.jb.faces.component.UIComponent;


public class MenuItemRenderer extends RendererImpl {
    long mid = 0;

    public StringBuffer renderBegin(WebContext pCtx, UIComponent itemToRender) {
        mid = 0;

        MenuItem mi = (MenuItem) itemToRender;
        pCtx.includeScript(HtmlConstants.MENU);
        StringBuffer stringBuffer = new StringBuffer("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" ");
        stringBuffer.append(getEditScript(pCtx, mi)).append(addTagProperty("width", mi.getWidth(), "100%"))
                    .append(addTagProperty("class", mi.getStyleClass(), null))
                    .append(addTagProperty("style", mi.getStyle(pCtx), null)).append("><tr>");

        if (mi.getChildCount() == 0) {
            stringBuffer.append("<td ").append(getEditScript(pCtx, mi)).append(">").append(mi.getValue()).append("</td>");
        }

        return stringBuffer;
    }

    public StringBuffer renderChildren(WebContext pCtx, UIComponent itemToRender) {
        StringBuffer stringBuffer = new StringBuffer();
        MenuItem mi = (MenuItem) itemToRender;

        for (int i = 0; i < mi.getChildCount(); i++) {
            stringBuffer.append(renderMenuItem(pCtx, (MenuItem) mi.getChild(i), "dropdown"));
        }

        return stringBuffer;
    }

    public StringBuffer renderEnd(WebContext pCtx, UIComponent itemToRender) {
        return new StringBuffer("<td align=\"right\" width=\"100%\"></td></tr></table>");
    }

    protected String getDisplayName(WebContext pCtx, MenuItem pMenuItem) {
        if ("-".equals(pMenuItem.getValue()) && isEditable(pCtx, pMenuItem)) {
            return "--";
        }

        String valueStr = (String) evaluate(pCtx, pMenuItem, pMenuItem.getValue());

        return isEmptyString(valueStr) ? ("MenuItem " + pMenuItem.getSequence()) : valueStr;
    }

    protected StringBuffer renderDropDown(WebContext pCtx, UIComponent itemToRender) {
        mid = 0;

        Menu mi = (Menu) itemToRender;

        StringBuffer stringBuffer = new StringBuffer("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" ");
        stringBuffer.append(getEditScript(pCtx, mi)).append(addTagProperty("style", mi.getStyle(pCtx), null)).append("><tr>");

        stringBuffer.append(renderChildren(pCtx, mi));

        if (mi.getChildCount() == 0) {
            stringBuffer.append("<td nowrap=\"nowrap\">").append(mi.getValue()).append("</td>");
        }

        return stringBuffer.append("</tr></table><div>");
    }

    protected StringBuffer renderMenuItem(WebContext pCtx, MenuItem mi, String pMode) {
        StringBuffer stringBuffer = new StringBuffer();
        StringBuffer scriptBuffer = new StringBuffer();

        String id = mi.getId();
        scriptBuffer.append("\n<script>\n<!--\n");
        scriptBuffer.append(renderSubmenu(pCtx, mi, true, pMode));
        scriptBuffer.append("\n//--></script>\n");

        pCtx.addPostBodyScript(scriptBuffer.toString());

        stringBuffer.append("<td >");

        //we make this special case is so that toolbar menu will
        //be activated only after click
        //while ones to design will be activated when mouse moved over them
        //hen its design time
        String activateStyle = "winMenuStyle";

        if (!pCtx.isRunTime() && (pCtx.getToolBar() != mi.getRoot())) {
            activateStyle = "designMenuStyle";
        }

        if (isEmptyString(mi.getIconImage())) {
            stringBuffer.append("<div ").append(addTagProperty("style", mi.getStyle(pCtx), null))
                        .append(addTagProperty("class", mi.getStyleClass(), "jbWinMenuItem"))
                        .append(getEditScript(pCtx, mi))
                        .append(" onMouseOver=\"" + activateStyle + ".menuMouseOver(event,this,'").append(id)
                        .append("','").append(pMode)
                        .append("');\" onMouseOut=\"" + activateStyle + ".menuMouseOut(this);\" ")
                        .append(" onMouseDown=\"" + activateStyle + ".menuMouseDown(event,this,'").append(id)
                        .append("','").append(pMode).append("');\" >");

            String valueStr = getDisplayName(pCtx, mi);
            stringBuffer.append(valueStr);
            stringBuffer.append("</div>");
        } else {
            stringBuffer.append("<img ").append(addTagProperty("style", mi.getStyle(pCtx), null))
                        .append(addTagProperty("class", mi.getStyleClass(), "jbWinMenuItem"))
                        .append(getEditScript(pCtx, mi)).append(addTagProperty(" src", mi.getIconImage(), null))
                        .append(" onMouseOver=\"" + activateStyle + ".menuMouseOver(event,this,'").append(id)
                        .append("','").append(pMode).append("');\"")
                        .append(" onMouseOut=\"" + activateStyle + ".menuMouseOut(this);\"")
                        .append(" onMouseDown=\"" + activateStyle + ".menuMouseDown(event,this,'").append(id)
                        .append("','").append(pMode).append("');\"").append("/>");
        }

        return stringBuffer.append("</td>");
    }

    protected StringBuffer renderSideMenu(WebContext pCtx, UIComponent itemToRender) {
        Menu mi = (Menu) itemToRender;
        StringBuffer stringBuffer = new StringBuffer("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\"");
        stringBuffer.append(getEditScript(pCtx, mi)).append(addTagProperty("width", mi.getWidth(), "100%"));

        stringBuffer.append(addTagProperty("style", mi.getStyle(pCtx), null)).append(">");

        int n = mi.getChildCount();

        for (int i = 0; i < n; i++) {
            stringBuffer.append("<tr>").append(renderMenuItem(pCtx, (MenuItem) mi.getChild(i), "sidemenu")).append("</tr>");
        }

        if (n == 0) {
            stringBuffer.append("<td >").append(mi.getValue()).append("</td>");
        }

        return stringBuffer.append("</tr></table>");
    }

    protected StringBuffer renderSubmenu(WebContext pCtx, MenuItem mi, boolean bRoot, String pMode) {
        StringBuffer scriptBuffer = new StringBuffer("");
        String id = mi.getId();

        String width = "120";

        if (mi.getChildCount() > 0) {
            width = mi.getChild(0).getWidth(); //take first item as template
        }

        if ((width == null) || (width.length() == 0)) {
            width = "120";
        }

        scriptBuffer.append("menu").append(id).append(" = new JBMenu('").append(id).append("','").append(width)
                    .append("','','").append(mi.getRoot().getId()).append("','").append(mi.getChildBoxStyle()).append("'," +
            isEditable(pCtx, mi) + ");\n");

        if (!bRoot) {
            scriptBuffer.append("menu" + ((MenuItem) mi.getParent()).getId() + ".items[\"menu" + id +
                "\"].setSubMenu(menu" + id + ")\n");
        }

        if (mi.getChildCount() == 0) {
        } else {
            scriptBuffer.append("with (menu").append(id).append(") {").append("\n");

            for (int i = 0; i < mi.getChildCount(); i++) {
                MenuItem childNode = (MenuItem) mi.getChild(i);
                String action = (String) evaluate(pCtx, childNode, childNode.getDestination());
                String dest = pCtx.formURL(action, childNode);

                if ((dest != null) && (dest.indexOf("http") == -1) && !isEmptyString(childNode.getOnUpdateModel())) {
                    dest += ("&source=" + childNode.getQName());
                }

                if (isEditable(pCtx, childNode)) {
                    dest = "javascript:jbDesigner.select(event, '" + pCtx.getPageName() + ".xsp','" +
                        childNode.getId() + "','" + childNode.getClientId() + "', true);";
                }

                String displayName = getDisplayName(pCtx, childNode);

                scriptBuffer.append("addMenuItem(new MenuItem(").append("\"").append(displayName).append("\",\"menu")
                            .append(childNode.getId()).append("\",\"").append(dest).append("\",true,'")
                            .append(childNode.getFontStyle()).append(childNode.getBackgroundStyle())
                            .append(childNode.getBorderStyle()).append("','").append(childNode.getHoverStyle())
                            .append("',\"").append(childNode.getId()).append("\",\"").append(childNode.getRoot().getId())
                            .append("\",\"")
                            .append((isEmptyString(childNode.getIconImage()) ? "" : childNode.getIconImage())).append("\"));\n");
            }

            scriptBuffer.append("}\n");

            for (int i = 0; i < mi.getChildCount(); i++) {
                MenuItem childNode = (MenuItem) mi.getChild(i);
                String displayName = getDisplayName(pCtx, childNode);

                if (((childNode.getChildCount() > 0) || isEditable(pCtx, childNode)) && !"--".equals(displayName)) {
                    scriptBuffer.append(renderSubmenu(pCtx, childNode, false, pMode));
                }
            }
        }

        if (this.isEditable(pCtx, mi)) {
            scriptBuffer.append("with (menu" + id + ") {").append("\n");

            String displayName = "add new item";
            long childId = mid++;
            scriptBuffer.append("addMenuItem(new MenuItem(").append("\"").append(displayName)
                        .append("\",\"menu" + childId).append("\",'" + mi.getRoot().getId() + ".xsp',true,'") //.append(mi.getStyle(pCtx))
            .append("','").append(mi.getHoverStyle()).append("',\"").append(mi.getClientId()).append("\",\"")
                        .append(mi.getRoot().getId()).append("\"));\n}\n");
        }

        return scriptBuffer;
    }
}
